using Microsoft.EntityFrameworkCore;
using ZZ_ICU.Models;
using ZZ_ICU.Services.Interfaces;

namespace ZZ_ICU.Services
{
    public class PatientService : IPatientService
    {
        private readonly ApplicationDbContext _db;

        public PatientService(ApplicationDbContext db)
        {
            _db = db;
        }

        public async Task<PatientsIndexViewModel> GetDashboardAsync(string currentNurse, bool onlyMine, bool showEmpty, string? selectedBed)
        {
            var allBedsQuery = _db.BedInfo.AsNoTracking().Where(b => !b.IsDel);
            var myBedsQuery = allBedsQuery.Where(b => b.Nurse == currentNurse);

            // 先计算统计数据
            var allPatientsCount = await (from b in allBedsQuery
                                          join p in _db.PatientViewInfo.AsNoTracking() on b.BedNo equals p.SickBed
                                          select b.BedNo).Distinct().CountAsync();

            var myPatientsCount = await (from b in myBedsQuery
                                         join p in _db.PatientViewInfo.AsNoTracking() on b.BedNo equals p.SickBed
                                         select b.BedNo).Distinct().CountAsync();

            // 然后查询床位数据
            IQueryable<BedInfo> baseBeds = onlyMine ? myBedsQuery : allBedsQuery;
            if (!showEmpty)
            {
                baseBeds = (from b in baseBeds
                            join p in _db.PatientViewInfo.AsNoTracking() on b.BedNo equals p.SickBed
                            select b).Distinct();
            }

            var data = await baseBeds
                .Select(b => new
                {
                    bed = b,
                    patient = _db.PatientViewInfo.AsNoTracking()
                        .Where(p => p.SickBed == b.BedNo)
                        .OrderByDescending(p => p.RKDate)
                        .ThenByDescending(p => p.Id)
                        .FirstOrDefault()
                })
                .OrderBy(x => x.bed.BedNo)
                .ToListAsync();

            var cards = new List<PatientSummaryViewModel>();
            PatientSummaryViewModel? selected = null;

            foreach (var x in data)
            {
                var summary = new PatientSummaryViewModel
                {
                    BedNo = x.bed.BedNo,
                    PatientName = x.patient?.name,
                    Sex = x.patient?.Sex,
                    ChargeNurse = x.patient?.ZRHuShi,
                    InDate = x.patient?.RKDate,
                    InDateTime = x.patient?.RKDate,
                    Diagnosis = x.patient?.Zhengduan,
                    DangerLevel = x.patient?.WXCD,
                    ChiefDoctor = x.patient?.ZYYiShi,
                    VisitNo = x.patient?.visitNo,
                    InHosNo = x.patient?.ZYNumber
                };

                if (x.patient?.Born != null)
                {
                    var now = DateTime.Today;
                    var age = now.Year - x.patient.Born.Value.Year;
                    if (x.patient.Born.Value.Date > now.AddYears(-age)) age--;
                    summary.Age = age;
                }

                if (x.patient != null)
                {
                    var inDays = (DateTime.Today - x.patient.RKDate.Date).Days + 1;
                    summary.InDays = inDays;
                }

                cards.Add(summary);
                if (!string.IsNullOrEmpty(selectedBed))
                {
                    if (summary.BedNo.Equals(selectedBed, StringComparison.OrdinalIgnoreCase))
                    {
                        selected = summary;
                    }
                }
                else if (selected == null && !string.IsNullOrEmpty(summary.PatientName))
                {
                    selected = summary;
                }
            }

            var vm = new PatientsIndexViewModel
            {
                CurrentNurseName = currentNurse,
                AllPatientsCount = allPatientsCount,
                MyPatientsCount = myPatientsCount,
                Cards = cards,
                ShowOnlyMine = onlyMine,
                ShowEmptyBeds = showEmpty,
                SelectedPatient = selected
            };

            return vm;
        }
    }
}

